<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>视频遮挡工具</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: #f5f5f5;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 10px;
            box-shadow: 0 5px 15px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 20px;
            text-align: center;
        }

        .header h1 {
            font-size: 2em;
            margin-bottom: 10px;
        }

        .header p {
            opacity: 0.9;
        }

        .main-content {
            padding: 20px;
        }

        .video-section {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-bottom: 20px;
        }

        .video-player {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
        }

        .video-player h3 {
            margin-bottom: 10px;
            color: #333;
        }

        .video-controls {
            margin-bottom: 10px;
        }

        .video-controls button {
            margin-right: 10px;
            padding: 8px 15px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 12px;
            background: #667eea;
            color: white;
        }

        .video-controls button:hover {
            background: #5a6fd8;
        }

        .video-controls button:disabled {
            background: #ccc;
            cursor: not-allowed;
        }

        #videoElement {
            width: 100%;
            max-width: 100%;
            border-radius: 5px;
        }

        .canvas-section {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
        }

        .canvas-section h3 {
            margin-bottom: 10px;
            color: #333;
        }

        .canvas-container {
            position: relative;
            border: 2px solid #ddd;
            border-radius: 5px;
            overflow: hidden;
        }

        #drawingCanvas {
            display: block;
            max-width: 100%;
            height: auto;
            cursor: crosshair;
        }

        .canvas-drawing {
            cursor: crosshair;
        }

        .canvas-dragging {
            cursor: grab;
        }

        .canvas-dragging:active {
            cursor: grabbing;
        }

        .controls {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 15px;
            margin-bottom: 20px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .control-group {
            display: flex;
            flex-direction: column;
            gap: 8px;
        }

        .control-group label {
            font-weight: 600;
            color: #333;
            font-size: 0.9em;
        }

        .control-group input, .control-group select {
            padding: 8px;
            border: 2px solid #e1e5e9;
            border-radius: 5px;
            font-size: 14px;
        }

        .control-group input:focus, .control-group select:focus {
            outline: none;
            border-color: #667eea;
        }

        .color-picker {
            display: flex;
            align-items: center;
            gap: 10px;
        }

        .color-picker input[type="color"] {
            width: 40px;
            height: 35px;
            border: none;
            border-radius: 5px;
            cursor: pointer;
        }

        .button-row {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-top: 15px;
            padding: 15px;
            background: #f8f9fa;
            border-radius: 8px;
        }

        .left-buttons {
            display: flex;
            gap: 10px;
        }

        .right-buttons {
            display: flex;
            gap: 10px;
        }

        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 5px;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
        }

        .btn-primary {
            background: #667eea;
            color: white;
        }

        .btn-primary:hover {
            background: #5a6fd8;
        }

        .btn-secondary {
            background: #6c757d;
            color: white;
        }

        .btn-secondary:hover {
            background: #5a6268;
        }

        .btn-danger {
            background: #dc3545;
            color: white;
        }

        .btn-danger:hover {
            background: #c82333;
        }

        .btn-success {
            background: #28a745;
            color: white;
        }

        .btn-success:hover {
            background: #218838;
        }

        .btn-warning {
            background: #ffc107;
            color: #212529;
        }

        .btn-warning:hover {
            background: #e0a800;
        }

        /* 预览模式相关样式 */
        .preview-controls {
            opacity: 0.6;
            transition: opacity 0.3s ease;
        }

        .preview-controls.active {
            opacity: 1;
        }

        .info-panel {
            background: #f8f9fa;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
        }

        .info-panel h3 {
            color: #333;
            margin-bottom: 15px;
        }

        .info-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
            gap: 15px;
        }

        .info-item {
            background: white;
            padding: 10px;
            border-radius: 5px;
            border-left: 3px solid #667eea;
        }

        .info-item h4 {
            color: #667eea;
            margin-bottom: 5px;
            font-size: 0.9em;
        }

        .info-item p {
            color: #666;
            font-size: 0.9em;
        }

        .mask-data {
            background: #e8f5e8;
            padding: 15px;
            border-radius: 8px;
            margin-top: 20px;
            border-left: 4px solid #28a745;
        }

        .mask-data h3 {
            color: #28a745;
            margin-bottom: 10px;
        }

        .mask-data pre {
            background: white;
            padding: 10px;
            border-radius: 5px;
            overflow-x: auto;
            font-size: 0.9em;
        }

        .mask-item {
            position: absolute;
            border: 2px solid #ff4757;
            background: rgba(255, 71, 87, 0.3);
            cursor: move;
        }

        .mask-resize-handle {
            position: absolute;
            width: 8px;
            height: 8px;
            background: #ff4757;
            border: 1px solid white;
            cursor: se-resize;
        }

        .resize-handle-n {
            top: -4px;
            left: 50%;
            transform: translateX(-50%);
            cursor: n-resize;
        }

        .resize-handle-s {
            bottom: -4px;
            left: 50%;
            transform: translateX(-50%);
            cursor: s-resize;
        }

        .resize-handle-e {
            right: -4px;
            top: 50%;
            transform: translateY(-50%);
            cursor: e-resize;
        }

        .resize-handle-w {
            left: -4px;
            top: 50%;
            transform: translateY(-50%);
            cursor: w-resize;
        }

        .resize-handle-ne {
            top: -4px;
            right: -4px;
            cursor: ne-resize;
        }

        .resize-handle-nw {
            top: -4px;
            left: -4px;
            cursor: nw-resize;
        }

        .resize-handle-se {
            bottom: -4px;
            right: -4px;
            cursor: se-resize;
        }

        .resize-handle-sw {
            bottom: -4px;
            left: -4px;
            cursor: sw-resize;
        }

        @media (max-width: 768px) {
            .video-section {
                grid-template-columns: 1fr;
            }
            
            .controls {
                grid-template-columns: 1fr;
            }
            
            .button-row {
                flex-direction: column;
                gap: 10px;
            }
            
            .left-buttons, .right-buttons {
                width: 100%;
                justify-content: center;
            }
            
            .btn {
                width: 100%;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🎬 视频遮挡工具</h1>
            <p>提取视频帧，绘制遮挡区块，生成遮挡视频</p>
        </div>

        <div class="main-content">
            <!-- 视频播放和画布区域 -->
            <div class="video-section">
                <div class="video-player">
                    <h3>📹 视频播放</h3>
                    <div class="video-controls">
                        <button id="loadVideo">选择视频</button>
                        <button id="playVideo">播放</button>
                        <button id="pauseVideo">暂停</button>
                        <button id="captureFrame">提取当前帧</button>
                    </div>
                    <video id="videoElement" controls>
                        您的浏览器不支持视频播放
                    </video>
                    <input type="file" id="videoFile" accept="video/*" style="display: none;">
                </div>

                <div class="canvas-section">
                    <h3>🎨 遮挡绘制</h3>
                    <div class="canvas-container">
                        <canvas id="drawingCanvas" width="800" height="450"></canvas>
                    </div>
                </div>
            </div>

            <!-- 控制面板 -->
            <div class="controls">
                <div class="control-group">
                    <label for="maskColor">遮挡颜色</label>
                    <div class="color-picker">
                        <input type="color" id="maskColor" value="#ff4757">
                        <span id="colorValue">#ff4757</span>
                    </div>
                </div>

                <div class="control-group">
                    <label for="maskOpacity">遮挡透明度</label>
                    <input type="range" id="maskOpacity" min="0" max="100" value="50">
                    <span id="opacityValue">50%</span>
                </div>

                <div class="control-group">
                    <label for="shapeType">绘制形状</label>
                    <select id="shapeType">
                        <option value="rectangle">矩形</option>
                        <option value="circle">圆形</option>
                        <option value="ellipse">椭圆</option>
                    </select>
                </div>
                
                <div class="control-group">
                    <label>
                        <input type="checkbox" id="previewMode" style="margin-right: 8px;">
                        预览模式
                    </label>
                    <small style="color: #666; font-size: 0.8em;">快速生成短视频预览效果</small>
                </div>
                
                <div class="control-group">
                    <label for="startTime">开始时间（秒）</label>
                    <input type="number" id="startTime" min="0" step="0.1" value="0" placeholder="0">
                </div>
                
                <div class="control-group">
                    <label for="duration">持续时间（秒）</label>
                    <input type="number" id="duration" min="0.1" step="0.1" value="5" placeholder="5">
                </div>
            </div>

            <!-- 操作按钮行 -->
            <div class="button-row">
                <div class="left-buttons">
                    <button class="btn btn-primary" id="startDraw">开始绘制</button>
                    <button class="btn btn-secondary" id="clearAll">清除所有</button>
                </div>
                <div class="right-buttons">
                    <button class="btn btn-success" id="getMaskData">获取遮挡数据</button>
                    <button class="btn btn-secondary" id="previewMask">🔍 预览效果</button>
                    <button class="btn btn-primary" id="applyMask">🎬 完整处理</button>
                </div>
            </div>

            <!-- 信息面板 -->
            <div class="info-panel">
                <h3>📊 状态信息</h3>
                <div class="info-grid">
                    <div class="info-item">
                        <h4>遮挡区块数量</h4>
                        <p id="blockCount">0</p>
                    </div>
                    <div class="info-item">
                        <h4>鼠标位置</h4>
                        <p id="mousePosition">(0, 0)</p>
                    </div>
                    <div class="info-item">
                        <h4>画布尺寸</h4>
                        <p id="canvasSize">800 x 450</p>
                    </div>
                    <div class="info-item">
                        <h4>绘制状态</h4>
                        <p id="drawStatus">未开始</p>
                    </div>
                </div>
            </div>

            <!-- 遮挡数据 -->
            <div class="mask-data">
                <h3>📋 遮挡区块数据</h3>
                <pre id="maskDataOutput">暂无遮挡数据</pre>
            </div>
        </div>
    </div>

    <script>
        class VideoMaskTool {
            constructor() {
                this.videoElement = document.getElementById('videoElement');
                this.canvas = document.getElementById('drawingCanvas');
                this.ctx = this.canvas.getContext('2d');
                this.masks = [];
                this.isDrawing = false;
                this.drawStart = null;
                this.currentFrame = null;
                this.selectedMask = null;
                this.isDragging = false;
                this.isResizing = false;
                this.dragOffset = { x: 0, y: 0 };
                this.resizeDirection = null;
                this.isMouseDown = false;
                
                this.initializeEventListeners();
                this.drawTestPattern();
            }
            
            initializeEventListeners() {
                // 视频控制
                document.getElementById('loadVideo').addEventListener('click', () => {
                    document.getElementById('videoFile').click();
                });

                document.getElementById('videoFile').addEventListener('change', (e) => {
                    this.loadVideo(e.target.files[0]);
                });

                document.getElementById('playVideo').addEventListener('click', () => {
                    this.videoElement.play();
                });

                document.getElementById('pauseVideo').addEventListener('click', () => {
                    this.videoElement.pause();
                });

                document.getElementById('captureFrame').addEventListener('click', () => {
                    this.captureCurrentFrame();
                });

                // 控制面板
                document.getElementById('maskColor').addEventListener('change', (e) => {
                    document.getElementById('colorValue').textContent = e.target.value;
                    this.updateAllMasks();
                });

                document.getElementById('maskOpacity').addEventListener('input', (e) => {
                    document.getElementById('opacityValue').textContent = e.target.value + '%';
                    this.updateAllMasks();
                });

                document.getElementById('startDraw').addEventListener('click', () => {
                    this.toggleDrawing();
                });

                document.getElementById('clearAll').addEventListener('click', () => {
                    this.clearAllMasks();
                });

                document.getElementById('getMaskData').addEventListener('click', () => {
                    this.getMaskData();
                });

                document.getElementById('applyMask').addEventListener('click', () => {
                    this.applyMaskToVideo();
                });

                document.getElementById('previewMask').addEventListener('click', () => {
                    this.previewMaskToVideo();
                });

                // 预览模式切换
                document.getElementById('previewMode').addEventListener('change', (e) => {
                    this.togglePreviewMode(e.target.checked);
                });

                // 画布事件
                this.canvas.addEventListener('mousedown', (e) => this.handleMouseDown(e));
                this.canvas.addEventListener('mousemove', (e) => this.handleMouseMove(e));
                this.canvas.addEventListener('mouseup', (e) => this.handleMouseUp(e));
                this.canvas.addEventListener('mouseleave', (e) => this.handleMouseLeave(e));
            }
            
            updateCanvasCursor() {
                if (this.isDrawing) {
                    this.canvas.classList.add('canvas-drawing');
                    this.canvas.classList.remove('canvas-dragging');
                } else {
                    this.canvas.classList.remove('canvas-drawing');
                    this.canvas.classList.add('canvas-dragging');
                }
            }
            
            drawTestPattern() {
                this.ctx.fillStyle = '#f0f0f0';
                this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
                
                this.ctx.fillStyle = '#333';
                this.ctx.font = '20px Arial';
                this.ctx.textAlign = 'center';
                this.ctx.fillText('视频遮挡工具', this.canvas.width/2, this.canvas.height/2);
                
                this.ctx.font = '14px Arial';
                this.ctx.fillText('选择视频并提取帧，然后绘制遮挡区块', this.canvas.width/2, this.canvas.height/2 + 30);
            }
            
            loadVideo(file) {
                if (!file) return;
                
                const url = URL.createObjectURL(file);
                this.videoElement.src = url;
                this.videoElement.load();
                
                // 启用视频控制按钮
                document.getElementById('playVideo').disabled = false;
                document.getElementById('pauseVideo').disabled = false;
                document.getElementById('captureFrame').disabled = false;
            }
            
            captureCurrentFrame() {
                if (this.videoElement.paused) {
                    alert('请先播放视频');
                    return;
                }
                
                // 创建临时canvas来捕获视频帧
                const tempCanvas = document.createElement('canvas');
                const tempCtx = tempCanvas.getContext('2d');
                
                tempCanvas.width = this.videoElement.videoWidth;
                tempCanvas.height = this.videoElement.videoHeight;
                
                // 绘制当前帧
                tempCtx.drawImage(this.videoElement, 0, 0);
                
                // 调整画布尺寸以匹配视频
                this.canvas.width = this.videoElement.videoWidth;
                this.canvas.height = this.videoElement.videoHeight;
                
                // 将帧绘制到主画布
                this.ctx.drawImage(tempCanvas, 0, 0);
                this.currentFrame = tempCanvas;
                
                this.updateCanvasSize();
                this.drawMasks();
                
                document.getElementById('drawStatus').textContent = '帧已提取，可以开始绘制';
            }
            
            drawMasks() {
                if (!this.currentFrame) return;
                
                // 重新绘制当前帧
                this.ctx.drawImage(this.currentFrame, 0, 0);
                
                // 绘制所有遮挡
                this.masks.forEach(mask => {
                    this.drawMask(mask);
                });
            }
            
            drawMask(mask) {
                this.ctx.save();
                this.ctx.globalAlpha = mask.opacity / 100;
                this.ctx.fillStyle = mask.color;
                
                if (mask.type === 'circle') {
                    const radius = Math.min(mask.width, mask.height) / 2;
                    const centerX = mask.x + mask.width / 2;
                    const centerY = mask.y + mask.height / 2;
                    
                    this.ctx.beginPath();
                    this.ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
                    this.ctx.fill();
                } else if (mask.type === 'ellipse') {
                    this.ctx.beginPath();
                    this.ctx.ellipse(mask.x + mask.width/2, mask.y + mask.height/2, 
                                   mask.width/2, mask.height/2, 0, 0, 2 * Math.PI);
                    this.ctx.fill();
                } else {
                    // 矩形
                    this.ctx.fillRect(mask.x, mask.y, mask.width, mask.height);
                }
                
                this.ctx.restore();
            }
            
            toggleDrawing() {
                this.isDrawing = !this.isDrawing;
                const btn = document.getElementById('startDraw');
                const status = document.getElementById('drawStatus');
                
                if (this.isDrawing) {
                    btn.textContent = '停止绘制';
                    btn.classList.remove('btn-primary');
                    btn.classList.add('btn-danger');
                    status.textContent = '绘制中';
                } else {
                    btn.textContent = '开始绘制';
                    btn.classList.remove('btn-danger');
                    btn.classList.add('btn-primary');
                    status.textContent = '未开始';
                }
                
                this.updateCanvasCursor();
            }
            
            handleMouseDown(e) {
                this.isMouseDown = true;
                const rect = this.canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                // 计算画布缩放比例
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                // 检查是否点击了调整手柄
                const resizeHandle = this.getResizeHandleAtPosition(x, y);
                if (resizeHandle) {
                    this.selectedMask = resizeHandle.mask;
                    this.isResizing = true;
                    this.resizeDirection = resizeHandle.direction;
                    return;
                }
                
                // 检查是否点击了现有遮挡
                const clickedMask = this.getMaskAtPosition(x, y);
                if (clickedMask) {
                    this.selectedMask = clickedMask;
                    this.isDragging = true;
                    this.dragOffset = { x: canvasX - clickedMask.x, y: canvasY - clickedMask.y };
                    return;
                }
                
                // 开始绘制新遮挡
                if (this.isDrawing) {
                    this.drawStart = { x: canvasX, y: canvasY };
                }
            }
            
            handleMouseMove(e) {
                const rect = this.canvas.getBoundingClientRect();
                const x = e.clientX - rect.left;
                const y = e.clientY - rect.top;
                
                // 计算画布缩放比例
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                document.getElementById('mousePosition').textContent = `(${Math.round(canvasX)}, ${Math.round(canvasY)})`;
                
                if (this.isDragging && this.selectedMask) {
                    // 拖拽遮挡
                    this.selectedMask.x = canvasX - this.dragOffset.x;
                    this.selectedMask.y = canvasY - this.dragOffset.y;
                    this.drawMasks();
                } else if (this.isResizing && this.selectedMask) {
                    // 调整遮挡大小
                    this.resizeMask(this.selectedMask, canvasX, canvasY);
                    this.drawMasks();
                } else if (this.isDrawing && this.drawStart && this.isMouseDown) {
                    // 绘制预览 - 只有在鼠标按下时才绘制
                    this.drawPreviewMask(this.drawStart, { x: canvasX, y: canvasY });
                }
            }
            
            handleMouseUp(e) {
                this.isMouseDown = false;
                
                if (this.isDrawing && this.drawStart) {
                    const rect = this.canvas.getBoundingClientRect();
                    const x = e.clientX - rect.left;
                    const y = e.clientY - rect.top;
                    
                    // 计算画布缩放比例
                    const scaleX = this.canvas.width / rect.width;
                    const scaleY = this.canvas.height / rect.height;
                    
                    // 转换为画布坐标
                    const canvasX = x * scaleX;
                    const canvasY = y * scaleY;
                    
                    const end = { x: canvasX, y: canvasY };
                    
                    // 只有当拖拽距离足够大时才创建遮挡
                    const distance = Math.sqrt(
                        Math.pow(end.x - this.drawStart.x, 2) + 
                        Math.pow(end.y - this.drawStart.y, 2)
                    );
                    
                    if (distance > 5) { // 最小拖拽距离
                        this.createMask(this.drawStart, end);
                    }
                    
                    this.drawStart = null;
                }
                
                this.isDragging = false;
                this.isResizing = false;
                this.selectedMask = null;
                this.resizeDirection = null;
            }
            
            handleMouseLeave(e) {
                this.isMouseDown = false;
                this.drawStart = null;
                this.isDragging = false;
                this.isResizing = false;
                this.selectedMask = null;
                this.resizeDirection = null;
            }
            
            getMaskAtPosition(x, y) {
                // 计算画布缩放比例
                const rect = this.canvas.getBoundingClientRect();
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                for (let i = this.masks.length - 1; i >= 0; i--) {
                    const mask = this.masks[i];
                    if (canvasX >= mask.x && canvasX <= mask.x + mask.width &&
                        canvasY >= mask.y && canvasY <= mask.y + mask.height) {
                        return mask;
                    }
                }
                return null;
            }
            
            getResizeHandleAtPosition(x, y) {
                // 计算画布缩放比例
                const rect = this.canvas.getBoundingClientRect();
                const scaleX = this.canvas.width / rect.width;
                const scaleY = this.canvas.height / rect.height;
                
                // 转换为画布坐标
                const canvasX = x * scaleX;
                const canvasY = y * scaleY;
                
                for (let i = this.masks.length - 1; i >= 0; i--) {
                    const mask = this.masks[i];
                    
                    // 检查8个方向的调整手柄
                    const handles = [
                        { x: mask.x + mask.width/2, y: mask.y - 4, direction: 'n' },
                        { x: mask.x + mask.width/2, y: mask.y + mask.height + 4, direction: 's' },
                        { x: mask.x + mask.width + 4, y: mask.y + mask.height/2, direction: 'e' },
                        { x: mask.x - 4, y: mask.y + mask.height/2, direction: 'w' },
                        { x: mask.x + mask.width + 4, y: mask.y - 4, direction: 'ne' },
                        { x: mask.x - 4, y: mask.y - 4, direction: 'nw' },
                        { x: mask.x + mask.width + 4, y: mask.y + mask.height + 4, direction: 'se' },
                        { x: mask.x - 4, y: mask.y + mask.height + 4, direction: 'sw' }
                    ];
                    
                    for (const handle of handles) {
                        if (canvasX >= handle.x - 4 && canvasX <= handle.x + 4 &&
                            canvasY >= handle.y - 4 && canvasY <= handle.y + 4) {
                            return { mask, direction: handle.direction };
                        }
                    }
                }
                return null;
            }
            
            resizeMask(mask, x, y) {
                const minSize = 10;
                
                switch (this.resizeDirection) {
                    case 'n':
                        const newHeight = mask.y + mask.height - y;
                        if (newHeight >= minSize) {
                            mask.height = newHeight;
                            mask.y = y;
                        }
                        break;
                    case 's':
                        const newHeight2 = y - mask.y;
                        if (newHeight2 >= minSize) {
                            mask.height = newHeight2;
                        }
                        break;
                    case 'e':
                        const newWidth = x - mask.x;
                        if (newWidth >= minSize) {
                            mask.width = newWidth;
                        }
                        break;
                    case 'w':
                        const newWidth2 = mask.x + mask.width - x;
                        if (newWidth2 >= minSize) {
                            mask.width = newWidth2;
                            mask.x = x;
                        }
                        break;
                    case 'ne':
                        const newHeight3 = mask.y + mask.height - y;
                        const newWidth3 = x - mask.x;
                        if (newHeight3 >= minSize && newWidth3 >= minSize) {
                            mask.height = newHeight3;
                            mask.y = y;
                            mask.width = newWidth3;
                        }
                        break;
                    case 'nw':
                        const newHeight4 = mask.y + mask.height - y;
                        const newWidth4 = mask.x + mask.width - x;
                        if (newHeight4 >= minSize && newWidth4 >= minSize) {
                            mask.height = newHeight4;
                            mask.y = y;
                            mask.width = newWidth4;
                            mask.x = x;
                        }
                        break;
                    case 'se':
                        const newHeight5 = y - mask.y;
                        const newWidth5 = x - mask.x;
                        if (newHeight5 >= minSize && newWidth5 >= minSize) {
                            mask.height = newHeight5;
                            mask.width = newWidth5;
                        }
                        break;
                    case 'sw':
                        const newHeight6 = y - mask.y;
                        const newWidth6 = mask.x + mask.width - x;
                        if (newHeight6 >= minSize && newWidth6 >= minSize) {
                            mask.height = newHeight6;
                            mask.width = newWidth6;
                            mask.x = x;
                        }
                        break;
                }
            }
            
            updateAllMasks() {
                const newColor = document.getElementById('maskColor').value;
                const newOpacity = parseInt(document.getElementById('maskOpacity').value);
                
                // 更新所有遮挡的颜色和透明度
                this.masks.forEach(mask => {
                    mask.color = newColor;
                    mask.opacity = newOpacity;
                });
                
                // 重新绘制
                this.drawMasks();
            }
            
            drawPreviewMask(start, end) {
                this.drawMasks();
                
                const color = document.getElementById('maskColor').value;
                const opacity = parseInt(document.getElementById('maskOpacity').value);
                const shapeType = document.getElementById('shapeType').value;
                
                this.ctx.save();
                this.ctx.globalAlpha = opacity / 100;
                this.ctx.fillStyle = color;
                
                if (shapeType === 'circle') {
                    const radius = Math.min(Math.abs(end.x - start.x), Math.abs(end.y - start.y)) / 2;
                    const centerX = Math.min(start.x, end.x) + Math.abs(end.x - start.x) / 2;
                    const centerY = Math.min(start.y, end.y) + Math.abs(end.y - start.y) / 2;
                    
                    this.ctx.beginPath();
                    this.ctx.arc(centerX, centerY, radius, 0, 2 * Math.PI);
                    this.ctx.fill();
                } else if (shapeType === 'ellipse') {
                    const centerX = Math.min(start.x, end.x) + Math.abs(end.x - start.x) / 2;
                    const centerY = Math.min(start.y, end.y) + Math.abs(end.y - start.y) / 2;
                    const radiusX = Math.abs(end.x - start.x) / 2;
                    const radiusY = Math.abs(end.y - start.y) / 2;
                    
                    this.ctx.beginPath();
                    this.ctx.ellipse(centerX, centerY, radiusX, radiusY, 0, 0, 2 * Math.PI);
                    this.ctx.fill();
                } else {
                    // 矩形 - 使用鼠标当前位置作为右下角
                    this.ctx.fillRect(
                        start.x,
                        start.y,
                        end.x - start.x,
                        end.y - start.y
                    );
                }
                
                this.ctx.restore();
            }
            
            createMask(start, end) {
                const shapeType = document.getElementById('shapeType').value;
                
                const mask = {
                    id: Date.now(),
                    type: shapeType,
                    x: Math.min(start.x, end.x),
                    y: Math.min(start.y, end.y),
                    width: Math.abs(end.x - start.x),
                    height: Math.abs(end.y - start.y),
                    color: document.getElementById('maskColor').value,
                    opacity: parseInt(document.getElementById('maskOpacity').value)
                };
                
                this.masks.push(mask);
                this.updateMaskCount();
                this.drawMasks();
            }
            
            clearAllMasks() {
                this.masks = [];
                this.updateMaskCount();
                this.drawMasks();
                this.updateMaskDataOutput();
            }
            
            updateMaskCount() {
                document.getElementById('blockCount').textContent = this.masks.length;
            }
            
            updateCanvasSize() {
                document.getElementById('canvasSize').textContent = 
                    `${this.canvas.width} x ${this.canvas.height}`;
            }
            
            getMaskData() {
                const masks = this.masks.map(mask => ({
                    id: mask.id,
                    type: mask.type,
                    x: Math.round(mask.x),
                    y: Math.round(mask.y),
                    width: Math.round(mask.width),
                    height: Math.round(mask.height),
                    color: mask.color,
                    opacity: mask.opacity
                }));
                
                const data = {
                    canvas: {
                        width: this.canvas.width,
                        height: this.canvas.height
                    },
                    masks: masks,
                    timestamp: new Date().toISOString()
                };
                
                this.updateMaskDataOutput(data);
                return data;
            }
            
            updateMaskDataOutput(data = null) {
                const output = document.getElementById('maskDataOutput');
                if (data) {
                    output.textContent = JSON.stringify(data, null, 2);
                } else {
                    output.textContent = '暂无遮挡数据';
                }
            }
            
            togglePreviewMode(enabled) {
                const startTimeInput = document.getElementById('startTime');
                const durationInput = document.getElementById('duration');
                
                if (enabled) {
                    startTimeInput.parentElement.classList.add('active');
                    durationInput.parentElement.classList.add('active');
                } else {
                    startTimeInput.parentElement.classList.remove('active');
                    durationInput.parentElement.classList.remove('active');
                }
            }

            async previewMaskToVideo() {
                if (this.masks.length === 0) {
                    alert('请先绘制遮挡区块！');
                    return;
                }
                
                if (!this.videoElement.src) {
                    alert('请先选择视频文件！');
                    return;
                }
                
                await this.processMaskVideo(true);
            }

            async processMaskVideo(isPreview = false) {
                try {
                    // 先获取遮挡数据
                    const maskData = this.getMaskData();
                    
                    // 创建FormData
                    const formData = new FormData();
                    
                    // 从视频URL创建文件对象
                    const response = await fetch(this.videoElement.src);
                    const blob = await response.blob();
                    const file = new File([blob], 'video.mp4', { type: 'video/mp4' });
                    
                    formData.append('video', file);
                    formData.append('mask_data', JSON.stringify(maskData));
                    
                    // 如果是预览模式或者勾选了预览模式，添加预览参数
                    if (isPreview || document.getElementById('previewMode').checked) {
                        formData.append('is_preview', 'true');
                        formData.append('start_time', document.getElementById('startTime').value || '0');
                        formData.append('duration', document.getElementById('duration').value || '5');
                    }
                    
                    // 显示处理状态
                    const statusText = isPreview ? '正在生成预览...' : '正在处理完整视频...';
                    document.getElementById('drawStatus').textContent = statusText;
                    
                    // 发送请求到后端
                    const apiResponse = await fetch('/video/mask', {
                        method: 'POST',
                        body: formData
                    });
                    
                    if (apiResponse.ok) {
                        // 下载文件
                        const resultBlob = await apiResponse.blob();
                        const url = window.URL.createObjectURL(resultBlob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = isPreview ? 'masked_preview.mp4' : 'masked_video.mp4';
                        document.body.appendChild(a);
                        a.click();
                        document.body.removeChild(a);
                        window.URL.revokeObjectURL(url);
                        
                        const successText = isPreview ? '预览生成完成！' : '完整视频处理完成！';
                        document.getElementById('drawStatus').textContent = successText;
                        alert(isPreview ? '预览视频生成成功！' : '遮挡视频生成成功！');
                    } else {
                        const errorData = await apiResponse.json();
                        throw new Error(errorData.error || '处理失败');
                    }
                    
                } catch (error) {
                    console.error('处理失败:', error);
                    document.getElementById('drawStatus').textContent = '处理失败';
                    alert('处理失败: ' + error.message);
                }
            }
            
            async applyMaskToVideo() {
                if (this.masks.length === 0) {
                    alert('请先绘制遮挡区块！');
                    return;
                }
                
                if (!this.videoElement.src) {
                    alert('请先选择视频文件！');
                    return;
                }
                
                await this.processMaskVideo(false);
            }
        }
        
        // 初始化工具
        document.addEventListener('DOMContentLoaded', () => {
            new VideoMaskTool();
        });
    </script>
</body>
</html> 